| EventStudio 2.5 Sequence diagram based system design and modeling | |
00001 00002 00003 00004 00005 00006 00007 00008 00009 #ifndef TRANSMIT_PROTOCOL_HANDLER_H 00010 #define TRANSMIT_PROTOCOL_HANDLER_H 00011 00012 #include "Retransmission_Buffer.h" 00013 #include "Packet_Queue.h" 00014 00023 00024 class Transmit_Protocol_Handler 00025 { 00026 enum {L2_HEADER_LENGTH=8}; 00027 00029 int m_next_Transmit_Sequence_Number; 00030 00033 int m_next_Receive_Sequence_Number; 00034 00036 Retransmission_Buffer m_retransmission_Buffer; 00037 00039 Packet_Queue<Datagram> m_transmit_Queue; 00040 00042 Protocol_Layer *m_p_Layer; 00043 00055 00056 void Transmit_Packet(Datagram *p_Packet) 00057 { 00058 // Add header and sequence numbers 00059 p_Packet->Add_Header(L2_HEADER_LENGTH); 00060 00061 p_Packet->Set_Receive_Sequence_Number(m_next_Receive_Sequence_Number); 00062 00063 // Fill the transmit sequence number and inform 00064 // retransmission queue if the packet is not 00065 // an acknowledgement packet 00066 if (p_Packet->GetType() != Datagram::ACKNOWLEDGEMENT) 00067 { 00068 p_Packet->Set_Transmit_Sequence_Number(m_next_Transmit_Sequence_Number); 00069 Modulo_Increment(m_next_Transmit_Sequence_Number); 00070 // Inform retransmission queue about the packet 00071 m_retransmission_Buffer.Add_Packet(p_Packet); 00072 } 00073 00074 // Pass on the message for transmission to the lower layer. A pointer to the lower 00075 // layer is obtained from the parent layer. 00076 Protocol_Layer *p_Lower_Layer = m_p_Layer->Get_Lower_Layer(); 00077 if (p_Lower_Layer) 00078 { 00079 p_Lower_Layer->Transmit(p_Packet); 00080 } 00081 } 00082 00083 public: 00084 00093 00094 Transmit_Protocol_Handler(Protocol_Layer *p_Layer) : 00095 m_p_Layer(p_Layer), m_retransmission_Buffer(p_Layer) 00096 { 00097 } 00098 00106 00107 void Handle_Transmit_Request(Datagram *p_Packet) 00108 { 00109 // Check for space in window 00110 if (m_retransmission_Buffer.Get_Window_Room() == 0) 00111 { 00112 // No space, window is full. The message waits 00113 // in the queue 00114 m_transmit_Queue.Add(p_Packet); 00115 } 00116 else 00117 { 00118 // If the window is open, transmit packet immediately 00119 Transmit_Packet(p_Packet); 00120 } 00121 } 00122 00133 00134 void Handle_Send_Ack_Request(int new_Receive_Sequence_Number) 00135 { 00136 // Copy the new receive sequence number 00137 // to acknowledge a packet 00138 m_next_Receive_Sequence_Number = new_Receive_Sequence_Number; 00139 00140 // If there are no more pending messages, 00141 // send an explicit acknowledgement message. If messages 00142 // are pending, ack can be piggy backed. 00143 if (m_transmit_Queue.Get_Length() == 0) 00144 { 00145 // No messages are pending transmission. 00146 // Send explicit ack 00147 Transmit_Packet(new Datagram(Datagram::ACKNOWLEDGEMENT)); 00148 } 00149 } 00150 00163 00164 void Handle_Received_Ack_Notification(int acknowledged_Sequence_Number) 00165 { 00166 Datagram *p_Packet; 00167 00168 // Delegate ack processing to Retransmission Buffer 00169 m_retransmission_Buffer.Handle_Received_Ack_Notification(acknowledged_Sequence_Number); 00170 00171 // Check if the transmit window has opened up. If there is is room in 00172 // the window, transmit packets waiting in the transmit queue 00173 int windowRoom = m_retransmission_Buffer.Get_Window_Room(); 00174 for (int i=0; i < windowRoom && m_transmit_Queue.Get_Length(); i++) 00175 { 00176 p_Packet = m_transmit_Queue.Remove(); 00177 Transmit_Packet(p_Packet); 00178 } 00179 } 00180 00181 }; 00182 #endif
1.3.4 | |
| Copyright © 2000-2005 EventHelix.com Inc. All Rights Reserved. |