Protocol Stack Design Pattern

来源:百度文库 编辑:神马文学网 时间:2024/04/29 02:28:23
Protocol Stack Documentation
Intent
We have already seen thatProtocol Layer andProtocol Packet provide astandardized interface between different layers of a protocol. The ProtocolStack design pattern takes advantage of the layer decoupling and provides amechanism for dynamic insertion and removal of protocol layers from a stack.
Also Known As
Protocol Layer Manager
Protocol Layer Collection
Motivation
Protocol stacks tend to be rigid in design and protocol layers cannot bedynamically added or removed from a protocol stack. This limits the use ofprotocol stacks in the even changing world of protocol standards. There areseveral scenarios where the layers in a protocol stack need to be changed on thefly. A few examples are:
An application detects the failure of the physical layer and decides to use a different medium to transport data. The application decides to change the lower layers of the protocol while keeping the upper layers intact.
The user has enabled encryption and this requires the sandwiching of the encryption layer between the network layer and the data-link layer.
The protocol stack designer needs to debug the interactions between the network layer and transport layer. This can be accomplished by sandwiching a pass-through logging layer that stores all the messages that get exchanged between the layers.
The Protocol Stack design pattern addresses this issue and introduces aflexible architecture for dynamic addition and removal of protocol layers.
Applicability
The Protocol Stack Design pattern can be used to implement any type oflayered protocol. It can be also used when different operations on an entityneed to be performed in a pipeline fashion. Each stage of the pipeline could bemodeled as a layer. This pattern is particularly useful in applicationsinvolving dynamic layer manipulation. A few applications are:
Changing the physical layer when the application detects failure of the physical layer.
Dynamically adding layers to handle demands from the user session (e.g. enabling encryption)
Debugging inter-layer interactions by adding a pass-through debug only layer.
Testing higher layers of a protocol by adding a special loop-back layer to connect the lower layer transmit and receive.
Emulating a node by configuring a echo-back layer to connect the higher layer transmit and receive.
Structure
The Protocol Stack Design Pattern is implemented by the Protocol Stack class.This class maintains a doubly linked list of active layers.
Participants
The key actors of this design pattern:
Protocol Stack: This class maintains a doubly linked list of Protocol layers. It supports dynamic addition and removal of protocol layers.
Protocol Layer: This is the base class for all protocol layers. The individual layers interface with each other via pointers to this class. The actual type of the upper layer and lower layer classes is not known to the implementers of a certain layer.
Collaboration
The following diagram shows the relationship and collaboration betweenvarious classes needed for the Datalink layer example.

Consequences
The Protocol Stack design pattern breaks down the rigid protocol layerstructure and provides a very flexible solution where layers can be dynamicallyadded and removed from the stack.
The figure below shows the flexibility of the pattern in supporting differentlayer organizations. The examples in the figure demonstrate:
A debug pass-through layer that displays the messages being exchanged between the datalink layer and the physical layer.
A loopback layer that facilitates the testing of the datalink and network layers by just looping back all transmitted messages back for receive.
An echo-back layer allows the protocol stack to emulate a node by just echoing back all higher layer messages back for transmission.
An encryption layer sandwiched between the datalink and physical layers. This layers encrypts and decrypts data that is passed between these layers.

Implementation
The Protocol Stack is implemented as a single class. The class maintains adoubly linked list of Protocol Layers. Important methods of the class are:
Handle_Transmit: This handler is invoked by the application to transmit messages using the protocol stack.
Handle_Receive: This handler is invoked by the device to pass received messages to the protocol stack.
Add_Layer: Add a protocol layer at a specific position in the protocol stack.
Remove_Layer: Remove a layer from the protocol stack.
Sample Code and Usage
The code for the Protocol Stack class ispresented below:
Protocol Stack Header File
00009 #ifndef PROTOCOL_STACK_H 00010 #define PROTOCOL_STACK_H 00011 00012 #include 00013 00014 classProtocol_Packet; 00015 classProtocol_Layer; 00016 00035 00037 { 00038 public: 00039 00042 { 00043 TOP, 00044 ABOVE, 00045 BELOW 00046 }; 00047 00048 voidHandle_Transmit(Protocol_Packet *p_Packet); 00049 voidHandle_Receive(Protocol_Packet *p_Packet); 00050 00051 voidAdd_Layer(Protocol_Layer *p_Layer, Placement placement = TOP,Protocol_Layer *p_Existing_Layer = NULL); 00052 voidRemove_Layer(Protocol_Layer *p_Layer); 00053 00054Protocol_Stack(); 00055 00056 private: 0005700061Protocol_Layer *m_p_Highest_Layer; 0006200066Protocol_Layer *m_p_Lowest_Layer; 00067 }; 00068 #endif
Protocol Stack Source File
00009 #include "Protocol_Stack.h" 00010 #include "Protocol_Layer.h" 00011 #include 00012 0002100022 voidProtocol_Stack::Handle_Transmit(Protocol_Packet *p_Packet) 00023 { 00024 if (m_p_Highest_Layer) 00025 { 00026m_p_Highest_Layer->Transmit(p_Packet); 00027 } 00028 } 00029 0003900040 voidProtocol_Stack::Handle_Receive(Protocol_Packet *p_Packet) 00041 { 00042 if (m_p_Lowest_Layer) 00043 { 00044m_p_Lowest_Layer->Handle_Receive(p_Packet); 00045 } 00046 } 00047 0006100062 voidProtocol_Stack::Add_Layer(Protocol_Layer *p_Layer, Placement placement,Protocol_Layer *p_Existing_Layer) 00063 { 00064 // Start with a clean slate. Initialize the upper and lower protocol 00065 // layers to NULL. The pointers will be suitably initialized after insertion. 00066 00067 p_Layer->Set_Lower_Layer(NULL); 00068 p_Layer->Set_Upper_Layer(NULL); 00069 00070 // Check if some other layer is already present in the protocol stack. 00071 // The placement processing applies only if this is not the first layer 00072 // being added to the stack. 00073 if (m_p_Highest_Layer) 00074 { 00075 // This is not the first layer 00076 00077 switch (placement) 00078 { 00079 case TOP: // Add the layer at the top 00080 assert(p_Existing_Layer == NULL); 00081m_p_Highest_Layer->Set_Upper_Layer(p_Layer); 00082 p_Layer->Set_Lower_Layer(m_p_Highest_Layer); 00083m_p_Highest_Layer = p_Layer; 00084 break; 00085 00086 case ABOVE: // Place the layer above the existing layer 00087 assert(p_Existing_Layer); 00088 00089Protocol_Layer *p_Previous_Upper_Layer; 00090 00091 // Linking up the new layer above the existing layer 00092 p_Previous_Upper_Layer = p_Existing_Layer->Get_Upper_Layer(); 00093 p_Layer->Set_Upper_Layer(p_Previous_Upper_Layer); 00094 p_Layer->Set_Lower_Layer(p_Existing_Layer); 00095 p_Existing_Layer->Set_Upper_Layer(p_Layer); 00096 00097 // Check if the existing layer was the highest layer 00098 if (p_Existing_Layer ==m_p_Highest_Layer) 00099 { 00100 // If it was, make the new layer the highest layer 00101m_p_Highest_Layer = p_Layer; 00102 } 00103 else 00104 { 00105 // Change the pointer of the existing layer's upper layer 00106 // to point to the newly inserted layer. 00107 p_Previous_Upper_Layer->Set_Lower_Layer(p_Layer); 00108 } 00109 break; 00110 00111 case BELOW: // Place the layer below the existing layer 00112 00113 assert(p_Existing_Layer); 00114Protocol_Layer *p_Previous_Lower_Layer; 00115 00116 // Linking up the new layer below the existing layer 00117 p_Previous_Lower_Layer = p_Existing_Layer->Get_Lower_Layer(); 00118 p_Layer->Set_Upper_Layer(p_Existing_Layer); 00119 p_Layer->Set_Lower_Layer(p_Previous_Lower_Layer); 00120 p_Existing_Layer->Set_Lower_Layer(p_Layer); 00121 00122 // Check if the existing layer was the lowest layer 00123 if (p_Existing_Layer ==m_p_Lowest_Layer) 00124 { 00125 // If it was, make the new layer the lowest layer 00126m_p_Lowest_Layer = p_Layer; 00127 } 00128 else 00129 { 00130 // Change the pointer of the existing layer's lower layer 00131 // to point to the newly inserted layer. 00132 p_Previous_Lower_Layer->Set_Upper_Layer(p_Layer); 00133 } 00134 break; 00135 00136 } 00137 } 00138 else // The highest layer is NULL 00139 { 00140 // This means that this is the first layer in the protocol stack. 00141 assert(p_Existing_Layer == NULL); 00142m_p_Highest_Layer = p_Layer; 00143m_p_Lowest_Layer = p_Layer; 00144 } 00145 } 00146 0015000151 voidProtocol_Stack::Remove_Layer(Protocol_Layer *p_Layer) 00152 { 00153 // Check if the layer to be removed is the highest layer. 00154 if (p_Layer ==m_p_Highest_Layer) 00155 { 00156 // Yes it is, so set the removed layer's lower layer as the highest layer 00157 // in the protocol stack. 00158m_p_Highest_Layer = p_Layer->Get_Lower_Layer(); 00159 00160 // If this was not the only layer in the stack, set the 00161 // upper layer of this layer as NULL. 00162 if (m_p_Highest_Layer) 00163 { 00164m_p_Highest_Layer->Set_Upper_Layer(NULL); 00165 } 00166 } 00167 else // Not the highest layer 00168 { 00169 // Stitch the upper layer to lower layer link after the layer is removed. 00170 (p_Layer->Get_Upper_Layer())->Set_Lower_Layer(p_Layer->Get_Lower_Layer()); 00171 } 00172 00173 // Check if the layer to be removed is the lowest layer. 00174 if (p_Layer ==m_p_Lowest_Layer) 00175 { 00176 // Yes it is, so set the removed layer's upper layer as the lowest layer 00177 // in the protocol stack. 00178m_p_Lowest_Layer = p_Layer->Get_Upper_Layer(); 00179 00180 // If this was not the only layer in the stack, set the 00181 // lower layer of this layer as NULL. 00182 if (m_p_Lowest_Layer) 00183 { 00184m_p_Lowest_Layer->Set_Lower_Layer(NULL); 00185 } 00186 } 00187 else 00188 { 00189 // Stitch the lower layer to upper layer link after the layer is removed. 00190 (p_Layer->Get_Lower_Layer())->Set_Upper_Layer(p_Layer->Get_Upper_Layer()); 00191 } 00192 00193 // Set the upper and lower layer pointers of the removed layer as NULL. 00194 // This is a safety measure. 00195 p_Layer->Set_Lower_Layer(NULL); 00196 p_Layer->Set_Upper_Layer(NULL); 00197 } 00198 0020100202Protocol_Stack::Protocol_Stack() 00203 { 00204m_p_Highest_Layer = NULL; 00205m_p_Lowest_Layer = NULL; 00206 }
Known Uses
The Protocol Stack design pattern can be used where ever a layered butdecoupled organization is required.
Related Patterns/Principles
Protocol Layer Design Pattern
Protocol Packet Design Pattern
Dependency Inversion Principle
Explore More...
Protocol Stack Documentation