BaseTcpSupport.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2010 Institut fuer Telematik, Karlsruher Institut fuer Technologie (KIT)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 //
00018 
00024 #include "BaseTcpSupport.h"
00025 #include <GlobalStatisticsAccess.h>
00026 #include <UDPSocket.h>
00027 #include <TCPCommand_m.h>
00028 #include <omnetpp.h>
00029 
00030 void BaseTcpSupport::handleTCPMessage(cMessage* msg)
00031 {
00032     TCPSocket* socket = sockets.findSocketFor(msg);
00033 
00034     if (socket == NULL) {
00035         socket = new TCPSocket(msg);
00036         socket->setCallbackObject(this);
00037         socket->setOutputGate(getTcpOut());
00038         sockets.addSocket(socket);
00039         TransportAddress newAddress =
00040                 TransportAddress(socket->getRemoteAddress(),
00041                                  socket->getRemotePort());
00042 
00043         socket->processMessage(msg);
00044         handleIncomingConnection(newAddress);
00045     } else {
00046         socket->processMessage(msg);
00047     }
00048 }
00049 
00050 void BaseTcpSupport::bindAndListenTcp(int port)
00051 {
00052     if (sockets.size() != 0) {
00053         return;
00054     }
00055 
00056     TCPSocket* newSocket = new TCPSocket();
00057     newSocket->bind(port);
00058     newSocket->setOutputGate(getTcpOut());
00059     newSocket->setCallbackObject(this);
00060     newSocket->listen();
00061     sockets.addSocket(newSocket);
00062 }
00063 
00064 bool BaseTcpSupport::isAlreadyConnected(TransportAddress address)
00065 {
00066     TCPSocket* newSocket = sockets.findSocketFor(address.getIp(),
00067                                                  address.getPort());
00068     if (newSocket == NULL) {
00069         return false;
00070     } else if (newSocket->getState() >= TCPSocket::PEER_CLOSED) {
00071         return false;
00072     } else return true;
00073 }
00074 
00075 void BaseTcpSupport::establishTcpConnection(TransportAddress address)
00076 {
00077     if (isAlreadyConnected(address)) {
00078         return;
00079     }
00080 
00081     TCPSocket* newSocket = new TCPSocket();
00082     newSocket->setOutputGate(getTcpOut());
00083     newSocket->setCallbackObject(this);
00084     newSocket->connect(address.getIp(), address.getPort());
00085 
00086     sockets.addSocket(newSocket);
00087 }
00088 
00089 void BaseTcpSupport::sendTcpData(cPacket *msg, TransportAddress address)
00090 {
00091     if (!isAlreadyConnected(address)) {
00092         handleConnectionEvent(NO_EST_CONNECTION, address);
00093         return;
00094     }
00095 
00096     TCPSocket* socket = sockets.findSocketFor(address.getIp(),
00097                                               address.getPort());
00098 
00099     if (socket->getState() == TCPSocket::CONNECTED) {
00100         socket->send(msg);
00101     }
00102 
00103     transQueue::iterator tx = queuedTx.find(address);
00104 
00105     if (tx != queuedTx.end()) {
00106         tx->second->push_back(msg);
00107     } else {
00108         msgQueue* newQueue = new msgQueue();
00109         newQueue->push_back(msg);
00110         queuedTx[address] = newQueue;
00111     }
00112 }
00113 
00114 void BaseTcpSupport::handleConnectionEvent(EvCode code, TransportAddress address)
00115 {
00116     if (code == NO_EST_CONNECTION) {
00117         establishTcpConnection(address);
00118     }
00119 }
00120 
00121 void BaseTcpSupport::handleDataReceived(TransportAddress address, cPacket* msg,
00122                                         bool urgent)
00123 {
00124 }
00125 
00126 void BaseTcpSupport::handleIncomingConnection(TransportAddress address)
00127 {
00128 }
00129 
00130 void BaseTcpSupport::socketDataArrived(int connId, void *yourPtr, cPacket *msg,
00131                                        bool urgent)
00132 {
00133     TCPSocket* socket = sockets.findSocketFor(connId);
00134     TransportAddress remoteAddress(socket->getRemoteAddress(),
00135                                    socket->getRemotePort());
00136 
00137     handleDataReceived(remoteAddress, msg, urgent);
00138 }
00139 
00140 void BaseTcpSupport::socketEstablished(int connId, void *yourPtr)
00141 {
00142     TCPSocket* socket = sockets.findSocketFor(connId);
00143 
00144     if (socket == NULL) {
00145         return;
00146     }
00147 
00148     TransportAddress remoteAddress(socket->getRemoteAddress(),
00149                                    socket->getRemotePort());
00150 
00151     transQueue::iterator tx = queuedTx.find(remoteAddress);
00152 
00153     if (tx != queuedTx.end()) {
00154         for (uint32 i = 0 ; i < tx->second->size(); i++) {
00155             socket->send(tx->second->at(i));
00156         }
00157 
00158         tx->second->clear();
00159         delete tx->second;
00160         queuedTx.erase(remoteAddress);
00161     }
00162 }
00163 
00164 void BaseTcpSupport::socketPeerClosed(int connId, void *yourPtr)
00165 {
00166     TCPSocket* socket = sockets.findSocketFor(connId);
00167     TransportAddress remoteAddress(socket->getRemoteAddress(),
00168                                    socket->getRemotePort());
00169 
00170     if (socket->getState() == TCPSocket::PEER_CLOSED) {
00171         socket->close();
00172         handleConnectionEvent(PEER_CLOSED, remoteAddress);
00173     }  else if (socket->getState() == TCPSocket::CLOSED) {
00174         sockets.removeSocket(socket);
00175         handleConnectionEvent(CONNECTION_SUCC_ClOSED, remoteAddress);
00176     }
00177 }
00178 
00179 void BaseTcpSupport::socketFailure(int connId, void *yourPtr, int code)
00180 {
00181     TCPSocket* socket = sockets.findSocketFor(connId);
00182     TransportAddress remoteAddress(socket->getRemoteAddress(),
00183                                    socket->getRemotePort());
00184 
00185     if (code == TCP_I_CONNECTION_REFUSED) {
00186         handleConnectionEvent(PEER_REFUSED, remoteAddress);
00187     } else if (code == TCP_I_TIMED_OUT) {
00188         handleConnectionEvent(PEER_TIMEDOUT, remoteAddress);
00189     } else if (code == TCP_I_CONNECTION_RESET) {
00190         handleConnectionEvent(CONNECTION_RESET, remoteAddress);
00191     } else {
00192         throw new cRuntimeError("Invalid error code on socketFailure.");
00193     }
00194 }
00195 
00196 void BaseTcpSupport::closeTcpConnection(TransportAddress address)
00197 {
00198     if (!isAlreadyConnected(address)) {
00199         return;
00200     }
00201 
00202     TCPSocket* oldSocket = sockets.findSocketFor(address.getIp(),
00203                                                  address.getPort());
00204 
00205     oldSocket->close();
00206 }