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.
685 lines
23 KiB
685 lines
23 KiB
/* 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
|
|
*/
|
|
|