|
|
/* 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 */
|