|
Home >
Real-time Mantra >
Design Patterns > Protocol Stack Design Pattern
|
We have already seen that Protocol Layer and Protocol Packet provide a standardized interface between different layers of a protocol. The Protocol Stack design pattern takes advantage of the layer decoupling and provides a mechanism for dynamic insertion and removal of protocol layers from a stack.
Protocol stacks tend to be rigid in design and protocol layers cannot be dynamically added or removed from a protocol stack. This limits the use of protocol stacks in the even changing world of protocol standards. There are several scenarios where the layers in a protocol stack need to be changed on the fly. A few examples are:
The Protocol Stack design pattern addresses this issue and introduces a flexible architecture for dynamic addition and removal of protocol layers.
The Protocol Stack Design pattern can be used to implement any type of layered protocol. It can be also used when different operations on an entity need to be performed in a pipeline fashion. Each stage of the pipeline could be modeled as a layer. This pattern is particularly useful in applications involving dynamic layer manipulation. A few applications are:
The Protocol Stack Design Pattern is implemented by the Protocol Stack class. This class maintains a doubly linked list of active layers.
The key actors of this design pattern:
The following diagram shows the relationship and collaboration between various classes needed for the Datalink layer example.

The Protocol Stack design pattern breaks down the rigid protocol layer structure and provides a very flexible solution where layers can be dynamically added and removed from the stack.
The figure below shows the flexibility of the pattern in supporting different layer organizations. The examples in the figure demonstrate:

The Protocol Stack is implemented as a single class. The class maintains a doubly linked list of Protocol Layers. Important methods of the class are:
The code for the Protocol Stack class is presented below:
| Protocol Stack Header File |
00009 #ifndef PROTOCOL_STACK_H 00010 #define PROTOCOL_STACK_H 00011 00012 #include <stdio.h> 00013 00014 class Protocol_Packet; 00015 class Protocol_Layer; 00016 00035 00036 class Protocol_Stack 00037 { 00038 public: 00039 00041 enum Placement 00042 { 00043 TOP, 00044 ABOVE, 00045 BELOW 00046 }; 00047 00048 void Handle_Transmit(Protocol_Packet *p_Packet); 00049 void Handle_Receive(Protocol_Packet *p_Packet); 00050 00051 void Add_Layer(Protocol_Layer *p_Layer, Placement placement = TOP, Protocol_Layer *p_Existing_Layer = NULL); 00052 void Remove_Layer(Protocol_Layer *p_Layer); 00053 00054 Protocol_Stack(); 00055 00056 private: 00057 00061 Protocol_Layer *m_p_Highest_Layer; 00062 00066 Protocol_Layer *m_p_Lowest_Layer; 00067 }; 00068 #endif |
| Protocol Stack Source File |
00009 #include "Protocol_Stack.h" 00010 #include "Protocol_Layer.h" 00011 #include <assert.h> 00012 00021 00022 void Protocol_Stack::Handle_Transmit(Protocol_Packet *p_Packet) 00023 { 00024 if (m_p_Highest_Layer) 00025 { 00026 m_p_Highest_Layer->Transmit(p_Packet); 00027 } 00028 } 00029 00039 00040 void Protocol_Stack::Handle_Receive(Protocol_Packet *p_Packet) 00041 { 00042 if (m_p_Lowest_Layer) 00043 { 00044 m_p_Lowest_Layer->Handle_Receive(p_Packet); 00045 } 00046 } 00047 00061 00062 void Protocol_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); 00081 m_p_Highest_Layer->Set_Upper_Layer(p_Layer); 00082 p_Layer->Set_Lower_Layer(m_p_Highest_Layer); 00083 m_p_Highest_Layer = p_Layer; 00084 break; 00085 00086 case ABOVE: // Place the layer above the existing layer 00087 assert(p_Existing_Layer); 00088 00089 Protocol_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 00101 m_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); 00114 Protocol_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 00126 m_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); 00142 m_p_Highest_Layer = p_Layer; 00143 m_p_Lowest_Layer = p_Layer; 00144 } 00145 } 00146 00150 00151 void Protocol_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. 00158 m_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 { 00164 m_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. 00178 m_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 { 00184 m_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 00201 00202 Protocol_Stack::Protocol_Stack() 00203 { 00204 m_p_Highest_Layer = NULL; 00205 m_p_Lowest_Layer = NULL; 00206 } |
The Protocol Stack design pattern can be used where ever a layered but decoupled organization is required.
| Explore More... |
|