windows-nt/Source/XPSP1/NT/enduser/netmeeting/t120/mst123/q922.h
2020-09-26 16:20:57 +08:00

685 lines
22 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Q922.h
*
* Copyright (c) 1993-1995 by DataBeam Corporation, Lexington, KY
*
* Abstract:
* This is the interface file for the Q.922 data link protocol.
* This class handles all error correction over the link. It also insures
* that all packets are sequenced properly. Its lower layer receives
* packets in raw Q922 format. It is responsible for framing and error
* detecting the packets. Q922 passes packets to its higher layer that
* have been sequenced properly.
*
* Q.922 is a full duplex protocol .
*
* This class assumes that the layers above and below it have packet input
* and output interfaces.
*
* Read the Q.922 specification before diving into the code.
*
* Caveats:
* None.
*
* Authors:
* James P. Galvin
* James W. Lawwill
*/
#ifndef _Q922_H_
#define _Q922_H_
/*
** Possible error conditions from this layer
*/
typedef enum
{
DATALINK_NO_ERROR,
DATALINK_READ_QUEUE_EMPTY,
DATALINK_WRITE_QUEUE_FULL,
DATALINK_RECEIVE_SEQUENCE_VIOLATION
}
DataLinkError, * PDataLinkError;
/*
** The data link layer can be in the following modes
*/
typedef enum
{
TEI_ASSIGNED,
AWAITING_ESTABLISHMENT,
MULTIPLE_FRAME_ESTABLISHED,
AWAITING_RELEASE,
TIMER_RECOVERY
}
DataLinkMode, * PDataLinkMode;
/*
** Q922 Disconnect Types
*/
typedef enum
{
DATALINK_NORMAL_DISCONNECT,
DATALINK_ILLEGAL_PACKET_RECEIVED,
DATALINK_RECEIVE_SEQUENCE_EXCEPTION,
DATALINK_REMOTE_SITE_TIMED_OUT
}
DataLinkDisconnectType, * PDataLinkDisconnectType;
/*
** Q922 Status messages
*/
typedef enum
{
DATALINK_TIMING_ERROR
}
DataLinkStatusMessage, * PDataLinkStatusMessage;
/*
** Default packet size
*/
#define DATALINK_OUTPUT_MAXIMUM_PACKET_SIZE 1024
/*
** Transmit and receive packets are managed via the DataQueue structure
*/
typedef struct
{
LPBYTE buffer_address;
USHORT length;
}
DataQueue, * PDataQueue;
/*
** In this implementation of Q922, the DLCI is 10 bits.
** For this reason, we will make it a USHORT
*/
typedef USHORT DLCI;
/*
** Q922 definitions
*/
#define COMMAND_BIT 0x02
#define POLL_FINAL_BIT 0x01
#define RESPONSE_FRAME COMMAND_BIT
#define COMMAND_FRAME 0x00
#define PF_RESET 0x00
#define PF_SET POLL_FINAL_BIT
#define UNNUMBERED_PF_RESET 0x00
#define UNNUMBERED_PF_SET 0x10
#define ADDRESS_BYTE_HIGH 0
#define ADDRESS_BYTE_LOW 1
#define CONTROL_BYTE_HIGH 2
#define CONTROL_BYTE_LOW 3
#define ADDRESS_MSB 0x00
#define ADDRESS_LSB 0x01
#define CONTROL_MSB 0x01
#define ADDRESS_HIGH(X) ((X >> 2) & 0xfc)
#define ADDRESS_LOW(X) ((X & 0x0f) << 4)
#define UNNUMBERED_HEADER_SIZE 3
#define SUPERVISORY_FRAME_BIT 0x01
#define SUPERVISORY_COMMAND_MASK 0x0c
#define RECEIVER_READY 0x00
#define RECEIVER_NOT_READY 0x04
#define REJECT 0x08
#define UNNUMBERED_FRAME_BIT 0x02
#define UNNUMBERED_COMMAND_MASK 0xec
#define SABME 0x6c
#define UNNUMBERED_ACKNOWLEDGE 0x60
#define FRAME_REJECT 0x84
#define DISCONNECTED_MODE 0x0c
#define DISC 0x40
#define SEQUENCE_MODULUS 128
#define RECEIVE_SEQUENCE_VIOLATION 1
/*
** DATALINK_MAXIMUM_PACKET_SIZE = User data + overhead
*/
#define DATALINK_MAXIMUM_PACKET_SIZE 1024
/*
** The maximum Q922 packet overhead is 4 bytes
*/
#define DATALINK_PACKET_OVERHEAD 4
/*
** Default timeouts
*/
#define DEFAULT_T203_COMM_TIMEOUT 600
#define DEFAULT_T203_TIMEOUT 30000
#define DEFAULT_MAXIMUM_T200_TIMEOUTS 5
class CLayerQ922 : public IProtocolLayer
{
public:
CLayerQ922(
T123 *owner_object,
Multiplexer *lower_layer,
USHORT message_base,
USHORT identifier,
BOOL link_originator,
USHORT data_indication_queue_size,
USHORT data_request_queue_size,
USHORT k_factor,
USHORT max_packet_size,
USHORT t200,
USHORT max_outstanding_bytes,
PMemoryManager memory_manager,
PLUGXPRT_PSTN_CALL_CONTROL,
PLUGXPRT_PARAMETERS *,
BOOL * initialized);
virtual ~CLayerQ922(void);
DataLinkError ReleaseRequest (void);
/*
** Functions overridden from the ProtocolLayer object
*/
ProtocolLayerError DataRequest (
ULONG_PTR identifier,
LPBYTE buffer_address,
ULONG length,
PULong bytes_accepted);
ProtocolLayerError DataRequest (
ULONG_PTR identifier,
PMemory memory,
PULong bytes_accepted);
ProtocolLayerError DataIndication (
LPBYTE buffer_address,
ULONG length,
PULong bytes_accepted);
ProtocolLayerError RegisterHigherLayer (
ULONG_PTR identifier,
PMemoryManager dr_memory_manager,
IProtocolLayer * higher_layer);
ProtocolLayerError RemoveHigherLayer (
ULONG_PTR identifier);
ProtocolLayerError PollTransmitter (
ULONG_PTR identifier,
USHORT data_to_transmit,
USHORT * pending_data,
USHORT * holding_data);
ProtocolLayerError PollReceiver(void);
ProtocolLayerError GetParameters (
USHORT * max_packet_size,
USHORT * prepend_size,
USHORT * append_size);
private:
void ProcessReadQueue (void);
void ProcessWriteQueue (
USHORT data_to_transmit);
BOOL TransmitSupervisoryFrame (
UChar frame_type,
UChar poll_final_bit);
BOOL TransmitInformationFrame (void);
BOOL TransmitUnnumberedFrame (void);
void ProcessReceiverReady (
LPBYTE packet_address,
USHORT packet_length);
void ProcessReceiverNotReady (
LPBYTE packet_address,
USHORT packet_length);
void ProcessReject (
LPBYTE packet_address,
USHORT packet_length);
BOOL ProcessInformationFrame (
LPBYTE packet_address,
USHORT packet_length);
DataLinkError ParsePacketHeader (
LPBYTE packet_address,
USHORT packet_length,
BOOL * command_frame,
LPBYTE receive_sequence_number,
BOOL * poll_final_bit);
void ProcessSABME (
LPBYTE packet_address,
USHORT packet_length);
void ProcessFrameReject (
LPBYTE packet_address,
USHORT packet_length);
void ProcessUnnumberedAcknowledge (
LPBYTE packet_address,
USHORT packet_length);
void ProcessDisconnectMode (
LPBYTE packet_address,
USHORT packet_length);
void ProcessDISC (
LPBYTE packet_address,
USHORT packet_length);
DataLinkError ParseUnnumberedPacketHeader (
LPBYTE packet_address,
BOOL * command_frame,
BOOL * poll_final_bit);
void UpdateAcknowledgeState (
UChar sequence_number);
void ResetSendState (
void);
void StartTimerT200 (void);
void StopTimerT200 (void);
void T200Timeout (
TimerEventHandle);
void StartTimerT203 (void);
void StopTimerT203 (void);
void T203Timeout (
TimerEventHandle);
void Reset (void);
private:
T123 *m_pT123; // owner object
Multiplexer *m_pMultiplexer; // lower layer
IProtocolLayer *Higher_Layer;
USHORT m_nMsgBase;
DLCI DLCI;
BOOL Link_Originator;
USHORT Maximum_Information_Size;
BOOL SABME_Pending;
BOOL Unnumbered_Acknowledge_Pending;
BOOL DISC_Pending;
BOOL Disconnected_Mode_Pending;
BOOL Frame_Reject_Pending;
USHORT Unnumbered_PF_State;
BOOL Final_Packet;
USHORT Data_Indication_Size;
PDataQueue Data_Indication;
LPBYTE Data_Indication_Buffer;
USHORT Data_Indication_Head;
USHORT Data_Indication_Tail;
USHORT Data_Indication_Count;
USHORT Data_Request_Size;
USHORT Data_Request_Total_Size;
PMemory *Data_Request;
USHORT Data_Request_Head;
USHORT Data_Request_Tail;
USHORT Data_Request_Count;
USHORT Data_Request_Acknowledge_Tail;
PMemoryManager Data_Request_Memory_Manager;
USHORT Lower_Layer_Prepend;
USHORT Lower_Layer_Append;
PMemory Supervisory_Write_Struct;
LPBYTE Supervisory_Write_Buffer;
UChar Send_State_Variable;
UChar Receive_State_Variable;
UChar Acknowledge_State_Variable;
BOOL Own_Receiver_Busy;
BOOL Peer_Receiver_Busy;
BOOL Command_Pending;
BOOL Poll_Pending;
BOOL Final_Pending;
BOOL Acknowledge_Pending;
BOOL Reject_Pending;
BOOL Reject_Outstanding;
ULONG T200_Timeout;
TimerEventHandle T200_Handle;
BOOL T200_Active;
ULONG N200_Count;
ULONG Maximum_T200_Timeouts;
ULONG Startup_Maximum_T200_Timeouts;
ULONG Link_Maximum_T200_Timeouts;
ULONG T203_Timeout;
TimerEventHandle T203_Handle;
BOOL T203_Active;
DataLinkMode Data_Link_Mode;
BOOL Link_Stable;
USHORT Receive_Sequence_Exception;
USHORT Receive_Sequence_Recovery;
USHORT Maximum_Outstanding_Packets;
USHORT Outstanding_Packets;
USHORT Maximum_Outstanding_Bytes;
USHORT Outstanding_Bytes;
ULONG Total_Retransmitted;
};
#endif
/*
* Documentation for Public class members
*/
/*
* CLayerQ922::CLayerQ922 (
* PTransportResources transport_resources,
* IObject * owner_object,
* IProtocolLayer * lower_layer,
* USHORT message_base,
* USHORT identifier,
* BOOL link_originator,
* USHORT data_indication_queue_siz,
* USHORT data_request_queue_size,
* USHORT k_factor,
* USHORT max_information_size,
* USHORT t200,
* USHORT max_outstanding_bytes,
* PMemoryManager memory_manager,
* BOOL * initialized)
*
* Functional Description
* This is the constructor for the Q.922 data link layer. It prepares
* for communications by allocating buffers and setting its internal
* buffers properly. It also registers itself with its lower layer.
*
* Formal Parameters
* transport_resources (i) - Pointer to TransportResources structure.
* owner_object (i) - Address of the object that owns us. This
* address is used for owner callbacks.
* lower_layer (i) - Address of the layer below us. We pass packets
* to this layer and receive packets from it.
* message_base (i) - Message base used in owner callbacks.
* identifier (i) - Identifier of this object. It is passed to the
* lower layer along with our address, to identify
* us.
* link_originator (i) - TRUE if this object should initiate a link.
* data_indication_queue_size (i) - Number of queues available for
* reception of data from the lower layer
* data_request_queue_size (i) - Number of queues available for
* transmission of data to the lower layer.
* k_factor (i) - Number of outstanding packets allowed.
* max_information_size (i) - Max. number of bytes in the information
* part of a packet
* t200 (i) - T200 timeout
* max_outstanding_bytes (i) - Maximum number of outstanding bytes at
* any one time
* initialized (o) - BOOL returned to user telling him if the
* object initialized o.k.
*
* Return Value
* None
*
* Side Effects
* None
*
* Caveats
* None
*/
/*
* CLayerQ922::~CLayerQ922 (void);
*
* Functional Description
* This is the destructor for the Q.922 data link layer. It destroys
* the read and write buffers.
*
* Formal Parameters
* None
*
* Return Value
* None
*
* Side Effects
* None
*
* Caveats
* None
*/
/*
* DataLinkError CLayerQ922::ReleaseRequest (void);
*
* Functional Description
* This function is called to terminate a connection. When this function
* is called we queue up a DISC packet to be sent to the remote site.
* When we receive an Unnumbered Ack packet, we notify the owner object
* that the link is terminated
*
* Formal Parameters
* None
*
* Return Value
* None
*
* Side Effects
* None
*
* Caveats
* None
*/
/*
* ProtocolLayerError CLayerQ922::DataRequest (
* ULONG identifier,
* PMemory memory,
* PULong bytes_accepted);
*
* Functional Description
* This function is called by a higher layer to request transmission of
* a packet. The packet is held in a memory object.
*
* Formal Parameters
* identifier (i) - Identifier of the higher layer
* memory (i) - Memory object containing packet.
* bytes_accepted (o) - Number of bytes accepted by the CLayerQ922.
* This value will either be 0 or the packet
* length since this layer has a packet interface.
*
* Return Value
* PROTOCOL_LAYER_NO_ERROR - No error occured
*
* Side Effects
* None
*
* Caveats
* None
*
*/
/*
* ProtocolLayerError CLayerQ922::DataRequest (
* ULONG identifier,
* LPBYTE buffer_address,
* USHORT length,
* USHORT * bytes_accepted);
*
* Functional Description
* This function is called by a higher layer to request transmission of
* a packet.
*
* Formal Parameters
* identifier (i) - Identifier of the higher layer
* buffer_address (i) - Buffer address
* length (i) - Length of packet to transmit
* bytes_accepted (o) - Number of bytes accepted by the CLayerQ922.
* This value will either be 0 or the packet
* length since this layer has a packet interface.
*
* Return Value
* PROTOCOL_LAYER_NO_ERROR - No error occured
*
* Side Effects
* None
*
* Caveats
* None
*/
/*
* ProtocolLayerError CLayerQ922::DataIndication (
* LPBYTE buffer_address,
* USHORT length,
* USHORT * bytes_accepted);
*
* Functional Description
* This function is called by the lower layer when it has data to pass up
* to us. This layer assumes that the data coming to us is in packet
* format.
*
* Formal Parameters
* buffer_address (i) - Buffer address
* length (i) - Number of bytes available
* bytes_accepted (o) - Number of bytes accepted
*
* Return Value
* PROTOCOL_LAYER_NO_ERROR - No error occured
*
* Side Effects
* None
*
* Caveats
* None
*
*/
/*
* ProtocolLayerError CLayerQ922::RegisterHigherLayer (
* ULONG identifier,
* PMemoryManager memory_manager,
* IProtocolLayer * higher_layer);
*
* Functional Description
* This function is called by the higher layer to register its identifier
* and its address. When this object needs to send a packet up, it calls
* the higher_layer with a Data Indication
*
* Formal Parameters
* identifier (i) - Unique identifier of the higher layer. If we
* were doing multiplexing at this layer, this
* would have greater significance.
* memory_manager (i) - Pointer to outbound memory manager
* higher_layer (i) - Address of higher layer
*
* Return Value
* PROTOCOL_LAYER_NO_ERROR - No error occured
* PROTOCOL_LAYER_REGISTRATION_ERROR - Error occured on registration
*
* Side Effects
* None
*
* Caveats
* None
*
*/
/*
* ProtocolLayerError CLayerQ922::RemoveHigherLayer (
* ULONG);
*
* Functional Description
* This function is called by the higher layer to remove its identifier
* and its address. If the higher layer removes itself from us, we have
* no place to send incoming data
*
* Formal Parameters
* None used
*
* Return Value
* PROTOCOL_LAYER_NO_ERROR - No error occured
*
* Side Effects
* None
*
* Caveats
* None
*/
/*
* ProtocolLayerError CLayerQ922::PollTransmitter (
* ULONG,
* USHORT data_to_transmit,
* USHORT * pending_data,
* USHORT * holding_data);
*
* Functional Description
* This function is called to give the CLayerQ922 a chance to transmit data
* in its Data_Request buffer.
*
* Formal Parameters
* identifier (i) - Not used
* data_to_transmit (i) - This is a mask that tells us to send Control
* data, User data, or both.
* pending_data (o) - Return value to indicate which data is left
* to be transmitted.
* holding_data (o) - Returns the number of packets currently
* outstanding.
*
* Return Value
* PROTOCOL_LAYER_NO_ERROR - No error occured
*
* Side Effects
* None
*
* Caveats
* None
*/
/*
* ProtocolLayerError CLayerQ922::PollReceiver (
* ULONG identifier);
*
* Functional Description
* This function is called to give the CLayerQ922 a chance pass packets
* to higher layers
*
* Formal Parameters
* identifier (i) - Not used
*
* Return Value
* PROTOCOL_LAYER_NO_ERROR - No error occured
*
* Side Effects
* None
*
* Caveats
* None
*/
/*
* ProtocolLayerError CLayerQ922::GetParameters (
* ULONG identifier,
* USHORT * max_packet_size,
* USHORT * prepend_size,
* USHORT * append_size);
*
* Functional Description:
* This function returns the maximum packet size that it can handle via
* its DataRequest() function.
*
* Formal Parameters
* identifier (i) - Not used
* max_packet_size (o) - Address to return max. packet size in.
* prepend_size (o) - Return number of bytes prepended to each packet
* append_size (o) - Return number of bytes appended to each packet
*
* Return Value
* PROTOCOL_LAYER_NO_ERROR - No error occured
*
* Side Effects
* None
*
* Caveats
* None
*/