Share

Receive Protocol Handler Pattern

Intent

Provide a common framework for receive direction sliding window protocol implementation.

Also Known As

  • Receive Protocol Design Pattern
  • Receiver Pattern
  • Sliding Window Receiver Pattern

Motivation

Different sliding window protocols have a lot of similarity. This similarity can be captured in a common design pattern for their implementation. Here we will focus on the receive side of the protocol.

Applicability

Receive Protocol Handler Pattern can be used to implement protocols at any layer.

Structure

This pattern is implemented by just one class, Receive Protocol Handler. This class receives the packets from the other end and performs the following operations:

  • Check validity of the received packet
  • Ask Transmit Protocol Handler to acknowledge the received packet
  • Check if the remote end has acknowledged that was sent by Transmit Protocol Handler.
  • Inform Transmit Protocol Handler about acknowledged packet.

To achieve this functionality, the following sequence numbers are maintained:

  • Next Expected Sequence Number: Transmit sequence number expected in the next packet from the remote end.
  • Last Acknowledged Sequence Number: Last receive sequence number received from the remote end. This sequence number is used by the remote end to acknowledge packets.

Participants

The Transmit and Receive Protocol Handlers are the main participants in this pattern. The received messages are added to the Receive Queue. The received message will be picked by the next higher layer.

Collaboration

The following diagram shows the relationship and collaboration between the Transmit Protocol Handler, Receive Protocol Handler and the Receive Queue classes.

Receive Protocol Handler

Consequences

Using this pattern simplifies the implementation of receive end point of a sliding window protocol. The design is flexible enough to adjust to any protocol.

Implementation

Handling of the received message is described below:

  1. Receive Protocol Handler's "Handle Received Packet" is invoked.
  2. Compare the packet's transmit sequence number with the expected sequence number.
  3. If the sequence number matches, take the following actions:
    1. Request Transmit Sequence Handler to acknowledge the just received packet.
    2. Add the message to the receive queue
    3. Modulo increment the next expected sequence number
  4. Compare the packet's receive sequence number with the last acknowledged sequence number. (Change in sequence number implies that an acknowledgement has been received from the other end).
  5. If a change is detected in the received sequence number, the following action is taken:
    1. Store the new receive sequence number as the last acknowledged sequence number.
    2. Inform the Transmit Protocol Handler about the acknowledgements received from the other end.

Sample Code and Usage

Here we present the code for a typical implementation of this pattern. Code is provided for the Receive Protocol Handler class. Receive Queue can be implemented using the message queue pattern.

Receive Protocol Handler

#include "Transmit_Protocol_Handler.h"

class Receive_Protocol_Handler
{
    enum {L2_HEADER_LENGTH=8};

    int m_next_Expected_Sequence_Number;

    int m_last_Acknowledged_Sequence_Number;

    Transmit_Protocol_Handler *m_p_Transmit_Protocol_Handler;

    Protocol_Layer *m_p_Layer;

public:   

    void Handle_Received_Packet(Datagram *p_Packet)
    {
        // Extract the header needed by this layer
        p_Packet->Extract_Header(L2_HEADER_LENGTH);

        // Compare the packet's transmit sequence number with 
        // the expected sequence number
        if (p_Packet->Get_Transmit_Sequence_Number() == m_next_Expected_Sequence_Number)
        {  
            // Request Transmit Sequence Handler to acknowledge 
            // the just received packet
            m_p_Transmit_Protocol_Handler->Handle_Send_Ack_Request(m_next_Expected_Sequence_Number);

            // Pass the message to the higher layer. The message is passed only if the upper layer
            // has been specified.
            Protocol_Layer *p_Upper_Layer = m_p_Layer->Get_Upper_Layer();
            if (p_Upper_Layer)
            {
                p_Upper_Layer->Handle_Receive(p_Packet);
            }

            // Modulo increment the next expected sequence number
            Modulo_Increment(m_next_Expected_Sequence_Number);
        }

        // Compare the packet's receive sequence number with the 
        // last acknowledged sequence number. (Change in sequence number 
        // implies that an acknowledgement has been received from the other end)
        if (p_Packet->Get_Receive_Sequence_Number() != m_last_Acknowledged_Sequence_Number)
        {
            // Update the last acknowledged sequence number
            m_last_Acknowledged_Sequence_Number = p_Packet->Get_Receive_Sequence_Number();

            // Inform the Transmit Protocol Handler about the 
            // acknowledgements received from the other end
            m_p_Transmit_Protocol_Handler->Handle_Received_Ack_Notification(
                m_last_Acknowledged_Sequence_Number);      
        }
    }


    Receive_Protocol_Handler(Protocol_Layer *p_Layer) :
    m_p_Layer(p_Layer)
    {
    }
};

Known Uses

  • Datalink layer sliding window protocol implementation
  • Higher layer sliding window protocol implementation

Related Patterns