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