Alex Bikfalvi
SimStream Documentation
ConnectionLayer.cpp
00001 #include "Headers.h" 00002 #include "ConnectionLayer.h" 00003 00004 CConnectionLayer::CConnectionLayer( 00005 CSimHandler* sim, 00006 __uint16 port, 00007 __uint32 connectionsMax, 00008 IDelegate5<void, __uint16, __uint16, CAddress, __byte, CPacket*>* delegateSend, 00009 IDelegate2<void, CConnectionReceiver*, CPacket*>* delegateRecv, 00010 IDelegate2<bool, CAddress, CPacket*>* delegateAccept, 00011 IDelegate1<void, CConnectionSender*>* delegateAccepted, 00012 __uint32 senderSegmentSize 00013 ) 00014 { 00015 assert(delegateSend); 00016 assert(delegateRecv); 00017 assert(delegateAccept); 00018 assert(delegateAccepted); 00019 00020 // Simulator 00021 this->sim = sim; 00022 00023 // Parameters 00024 this->port = port; 00025 this->connectionsMax = connectionsMax; 00026 this->connectionsNum = 0; 00027 00028 // Delegates 00029 this->delegateSend = delegateSend; 00030 this->delegateRecv = delegateRecv; 00031 this->delegateAccept = delegateAccept; 00032 this->delegateAccepted = delegateAccepted; 00033 00034 // Delegates (local) 00035 this->delegateDispose = new Delegate1<CConnectionLayer, void, CConnection*>(this, &CConnectionLayer::Dispose); 00036 00037 // Sender 00038 this->senderSegmentSize = senderSegmentSize; 00039 00040 // Connections 00041 this->connections = new CConnectionEntry[this->connectionsMax]; 00042 00043 // Connection entries 00044 for(__uint32 index = 0; index < this->connectionsMax; index++) 00045 this->connections[index].Entry(index); 00046 00047 // Connection free list 00048 this->connectionsFree = this->connections; 00049 for(__uint32 index = 1; index < this->connectionsMax; index++) 00050 { 00051 this->connections[index-1].Next(&this->connections[index]); 00052 this->connections[index].Prev(&this->connections[index-1]); 00053 } 00054 00055 // Receivers allocated list 00056 this->connectionsAlloc = NULL; 00057 } 00058 00059 CConnectionLayer::~CConnectionLayer() 00060 { 00061 // Connections 00062 for(__uint32 index = 0; index < this->connectionsMax; index++) 00063 if(this->connections[index].State() == CConnectionEntry::ASSIGNED) 00064 delete this->connections[index].Connection(); 00065 00066 delete[] this->connections; 00067 00068 // Delegates 00069 delete this->delegateDispose; 00070 } 00071 00072 CConnectionLayer::EResult CConnectionLayer::Create(CAddress dstAddress, __uint16 dstPort, CConnectionReceiver** receiver) 00073 { 00074 // Create a receiver connection 00075 00076 // Check if there is a free connection entry 00077 if(this->IsAvailable()) 00078 { 00079 // Allocate entry 00080 __uint32 entry = this->Alloc(); 00081 00082 // Create the connection 00083 CConnectionReceiver* connection = new CConnectionReceiver( 00084 entry, 00085 this->port, 00086 this->sim, 00087 this->delegateSend, 00088 this->delegateRecv, 00089 this->delegateDispose, 00090 dstAddress, 00091 dstPort 00092 ); 00093 00094 // Assign the connection to the entry 00095 this->Assign(connection); 00096 00097 // Set receiver 00098 *receiver = connection; 00099 00100 return SUCCESS; 00101 } 00102 else return FAIL_MAX_CONNECTIONS_REACHED; 00103 } 00104 00105 00106 __uint32 CConnectionLayer::Alloc() 00107 { 00108 // Allocate connection entry 00109 assert(this->connectionsNum < this->connectionsMax); 00110 assert(this->connectionsFree != NULL); 00111 00112 // Get connection entry from the beginning of the free list 00113 CConnectionEntry* connectionEntry = this->connectionsFree; 00114 00115 // Check entry is free 00116 assert(connectionEntry->State() == CConnectionEntry::FREE); 00117 00118 // Shift the beginning of the free list 00119 if(this->connectionsFree->Next()) this->connectionsFree->Next()->Prev(NULL); 00120 this->connectionsFree = this->connectionsFree->Next(); 00121 00122 // Add the entry to the beginning of the allocated list 00123 connectionEntry->Next(this->connectionsAlloc); 00124 connectionEntry->Prev(NULL); 00125 if(this->connectionsAlloc) this->connectionsAlloc->Prev(connectionEntry); 00126 this->connectionsAlloc = connectionEntry; 00127 00128 // Mark the entry as allocated 00129 connectionEntry->Alloc(); 00130 00131 // Increment number of connections 00132 this->connectionsNum++; 00133 00134 return connectionEntry->Entry(); 00135 } 00136 00137 void CConnectionLayer::Assign(CConnection* connection) 00138 { 00139 assert(connection); 00140 assert(connection->IdEntry() < this->connectionsMax); 00141 00142 // Get the connection entry 00143 CConnectionEntry* connectionEntry = &this->connections[connection->IdEntry()]; 00144 00145 // Check the connection entry is allocated 00146 assert(connectionEntry->State() == CConnectionEntry::ALLOC); 00147 00148 // Assign the connection to the entry 00149 connectionEntry->Assign(connection); 00150 } 00151 00152 void CConnectionLayer::Free(__uint32 entry) 00153 { 00154 // Free receiver entry 00155 assert(this->connectionsNum > 0); 00156 assert(entry < this->connectionsMax); 00157 00158 // Get the connection entry 00159 CConnectionEntry* connectionEntry = &this->connections[entry]; 00160 00161 // Check the entry state (either allocated or assigned) 00162 assert(connectionEntry->State() != CConnectionEntry::FREE); 00163 00164 // Remove the entry from the allocated list 00165 if(connectionEntry->Prev()) connectionEntry->Prev()->Next(connectionEntry->Next()); 00166 if(connectionEntry->Next()) connectionEntry->Next()->Prev(connectionEntry->Prev()); 00167 if(this->connectionsAlloc == connectionEntry) this->connectionsAlloc = this->connectionsAlloc->Next(); 00168 00169 // Add the entry to the beginning of the free list 00170 connectionEntry->Next(this->connectionsFree); 00171 connectionEntry->Prev(NULL); 00172 if(this->connectionsFree) this->connectionsFree->Prev(connectionEntry); 00173 this->connectionsFree = connectionEntry; 00174 00175 // Increment number of connections 00176 this->connectionsNum--; 00177 00178 // Change the state to free 00179 connectionEntry->Free(); 00180 } 00181 00182 bool CConnectionLayer::IsAvailable() 00183 { 00184 return this->connectionsNum < this->connectionsMax; 00185 } 00186 00187 CConnectionLayer::EResult CConnectionLayer::Recv(CAddress srcAddress, __uint16 srcPort, __uint16 dstPort, CPacketConnection* packet) 00188 { 00189 // Received connection packet 00190 00191 // Check transport layer port 00192 if(dstPort != this->port) return FAIL_INCORRECT_PORT; 00193 00194 // If the packet destination is not set 00195 if(packet->Dst() == PACKET_INVALID_CONNECTION) 00196 { 00197 // Check if the packet is a connection message 00198 if(packet->TypeConnection() == CPacketConnection::MESSAGE) 00199 { 00200 // Check if the packet is an OPEN message 00201 CPacketConnectionMessage* message = type_cast<CPacketConnectionMessage*>(packet); 00202 00203 if(message->TypeMessage() == CPacketConnectionMessage::OPEN) 00204 { 00205 // Send the OPEN request information to the client 00206 if((*this->delegateAccept)(srcAddress, packet->Payload())) 00207 { 00208 // If the upper layer accepts the connection, check if there is a free connection entry 00209 assert(this->IsAvailable()); 00210 if(this->IsAvailable()) 00211 { 00212 // Allocate a new connection entry 00213 __uint32 entry = this->Alloc(); 00214 00215 // Create a new sender connection 00216 CConnectionSender* connection = new CConnectionSender( 00217 entry, 00218 this->port, 00219 this->sim, 00220 this->delegateSend, 00221 this->delegateDispose, 00222 srcAddress, 00223 srcPort, 00224 message->Src(), 00225 message->SrcEntry(), 00226 this->senderSegmentSize 00227 ); 00228 00229 // Assign the connection to the entry 00230 this->Assign(connection); 00231 00232 // Send the packet to the connection 00233 type_cast<CConnection*>(connection)->Recv(srcAddress, packet); 00234 00235 // Send the connection to the upper layer 00236 (*this->delegateAccepted)(connection); 00237 00238 return SUCCESS; 00239 } 00240 else return FAIL_MAX_CONNECTIONS_REACHED; 00241 } 00242 else return FAIL_NOT_ACCEPTED; 00243 } 00244 else return FAIL_INVALID_DESTINATION_MESSAGE; 00245 } 00246 else return FAIL_INVALID_DESTINATION_PACKET; 00247 } 00248 else 00249 { 00250 // Check the packet 00251 assert(packet->DstEntry() < this->connectionsMax); 00252 00253 // Get the connection entry 00254 CConnectionEntry* connectionEntry = &this->connections[packet->DstEntry()]; 00255 00256 // If there is an assigned connection entry for the destination of this packet 00257 if(connectionEntry->State() == CConnectionEntry::ASSIGNED) 00258 { 00259 // If the endpoint is the destination of this packet 00260 if(connectionEntry->Connection()->Id() == packet->Dst()) 00261 { 00262 // Pass the packet to the connection 00263 connectionEntry->Connection()->Recv(srcAddress, packet); 00264 00265 return SUCCESS; 00266 } 00267 } 00268 return FAIL_CONNECTION_NOT_EXIST; 00269 } 00270 } 00271 00272 CConnection* CConnectionLayer::Get(__uint32 id, __uint32 idEntry) 00273 { 00274 // Get the connection entry 00275 CConnectionEntry* connectionEntry = &this->connections[idEntry]; 00276 00277 if(connectionEntry->State() != CConnectionEntry::ASSIGNED) return NULL; 00278 if(connectionEntry->Connection()->Id() != id) return NULL; 00279 00280 return connectionEntry->Connection(); 00281 } 00282 00283 00284 void CConnectionLayer::Dispose(CConnection* connection) 00285 { 00286 assert(connection); 00287 00288 // Free the connection entry 00289 this->Free(connection->IdEntry()); 00290 00291 // Delete the connection 00292 delete connection; 00293 }
Last updated: February 8, 2011