Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

# Platform/Aperios1.3.2/TCPEndpoint.cpp

Go to the documentation of this file.

    00001 /**
    00002 * @file  Platform/Aperios1.3.2/TCPEndpoint.cpp
    00003 *
    00004 * Implementation for IP Communication Classes
    00005 * @attention this is the Aperios implementation
    00006 *
    00007 * @author <A href=mailto:robocup@m-wachter.de>Michael Wachter</A>
    00008 *
    00009 */
    00010
    00011 #include "TCPEndpoint.h"
    00012 #include <TCPEndpointMsg.h>
    00013 #include <stdio.h>
    00014 #include <iostream.h>
    00015
    00016 #define MAXSENDSIZE 8192
    00017
    00018 TCPEndpoint::TCPEndpoint(int sendBufferSize, int receiveBufferSize)
    00019 :IPEndpoint(sendBufferSize, receiveBufferSize)
    00020 {
    00021    status=closed;
    00022    address="";
    00023    port=0;
    00024    wasListening=false;
    00025 }
    00026
    00027 TCPEndpoint::TCPEndpoint(char* address,int port)
    00028 : IPEndpoint()
    00029 {
    00030    connect(address, port);
    00031 }
    00032
    00033 TCPEndpoint::~TCPEndpoint()
    00034 {
    00035    close();
    00036 }
    00037
    00038
    00039
    00040 /*
    00041  * Start connecting
    00042  */
    00043
    00044 int TCPEndpoint::connect(char* address, int port)
    00045 {
    00046
    00047    antEnvCreateEndpointMsg tcpCreateMsg( EndpointType_TCP, 8192);
    00048    tcpCreateMsg.Call(ipStackRef, sizeof(tcpCreateMsg));
    00049
    00050    if (tcpCreateMsg.error != ANT_SUCCESS)
    00051    {
    00052      cout << "TCPEndpoint::connect(): Can't create Endpoint, error " << antErrorString(tcpCreateMsg.error);
    00053      return(1);
    00054    }
    00055
    00056    endpoint = tcpCreateMsg.moduleRef;
    00057
    00058    // cout << "TCPEndpoint: Connecting to " << address << ":" << port << "\n";
    00059
    00060    TCPEndpointConnectMsg connectMsg(endpoint, IP_ADDR_ANY, IP_PORT_ANY,
    00061                                         address, port);
    00062
    00063    connectMsg.continuation = this;
    00064    connectMsg.Send(ipStackRef, *myOID_ , *connectContSelector, sizeof(connectMsg));
    00065
    00066    status=connecting;
    00067    return(0);
    00068 }
    00069
    00070 void TCPEndpoint::connectCont(antEnvMsg* msg)
    00071 {
    00072     // cout << "TCPEndpoint: ConnectCont \n" << flush;
    00073     TCPEndpointConnectMsg* connectMsg = (TCPEndpointConnectMsg*) msg;
    00074     if (connectMsg->error != TCP_SUCCESS)
    00075     {
    00076        cout << "TCPEndpoint::connectCont() Connection failed : " <<
    00077                    getErrorString(connectMsg->error) << " \n";
    00078        status = closed;
    00079     }
    00080     else
    00081     {
    00082        status = connected;
    00083     }
    00084
    00085
    00086     if(status==connected)
    00087     {
    00088        onConnect();
    00089        startReceiving();
    00090     }
    00091 }
    00092
    00093
    00094 void TCPEndpoint::onConnect()
    00095 {
    00096
    00097
    00098 }
    00099
    00100 // Start listening
    00101 int TCPEndpoint::listen(int listenPort)
    00102 {
    00103    antEnvCreateEndpointMsg tcpCreateMsg( EndpointType_TCP, 8192);
    00104    tcpCreateMsg.Call(ipStackRef, sizeof(tcpCreateMsg));
    00105
    00106    if (tcpCreateMsg.error != ANT_SUCCESS)
    00107    {
    00108      cout << "TCPEndpoint::listen() : Can't create Endpoint, error " << antErrorString(tcpCreateMsg.error);
    00109      return(1);
    00110    }
    00111
    00112    endpoint = tcpCreateMsg.moduleRef;
    00113
    00114   cout << "TCPEndpoint::listen(" << listenPort << ") \n";
    00115   port = listenPort;
    00116
    00117   TCPEndpointListenMsg listenMsg(endpoint, IP_ADDR_ANY, port);
    00118   listenMsg.continuation=this;
    00119   VERIFY(*listenContSelector!=0); // Selectors not in construktor
    00120   listenMsg.Send(ipStackRef, *myOID_, *listenContSelector, sizeof(listenMsg));
    00121
    00122   status=listening;
    00123
    00124   return(0);
    00125 }
    00126
    00127
    00128 // Called by Aperios
    00129 void TCPEndpoint::listenCont(antEnvMsg* msg)
    00130 {
    00131   // cout << "TCPEndpoint::listenCont() \n";
    00132   TCPEndpointListenMsg* listenMsg = (TCPEndpointListenMsg*) msg;
    00133   if (listenMsg->error != TCP_SUCCESS)
    00134   {
    00135      cout << "TCPEndpoint::listenCont() : Listen failed : " <<
    00136           getErrorString(listenMsg->error) << "\n";
    00137
    00138      return;
    00139
    00140   }
    00141   else
    00142   {
    00143      status=connected;
    00144      wasListening=true;
    00145      onConnect();
    00146      startReceiving();
    00147
    00148   }
    00149
    00150 }
    00151
    00152 // Sending
    00153
    00154 int TCPEndpoint::send(void* data,int size)
    00155 {
    00156    // cout << "TCPEndpoint::send(" << data << "," << size<< ") " << SystemCall::getCurrentSystemTime() << " \n";
    00157    sendDataBuffer = data;
    00158    sizeOfDataToSend = size;
    00159
    00160    if (status == connected)
    00161    {
    00162        if (status != sending)
    00163        {
    00164            if (size>MAXSENDSIZE) size=MAXSENDSIZE;
    00165            memcpy(sharedSendBuffer,sendDataBuffer,size);  // Copy data into shared memory buffer
    00166
    00167       //     cout << "TCPEndpoint::send - Transfering " << size << " from " << sendDataBuffer << "\n";
    00168            sendSendMessage(size);
    00169
    00170            (char*)sendDataBuffer += size;
    00171            sizeOfDataToSend-=size;
    00172
    00173            return(0);
    00174        }
    00175        else
    00176        {
    00177          return(-1);
    00178        }
    00179    }
    00180    else
    00181    {
    00182      cout << "TCPEndpoint::send() : Not connected \n";
    00183      return(-2);
    00184    }
    00185
    00186 }
    00187
    00188 void TCPEndpoint::sendCont(antEnvMsg* msg)
    00189 {
    00190     // cout << "TCPEndpoint::SendCont " << SystemCall::getCurrentSystemTime() << "\n";
    00191
    00192     TCPEndpointSendMsg* sendMsg = (TCPEndpointSendMsg*) msg;
    00193     if (sendMsg->error != TCP_SUCCESS)
    00194     {
    00195         cout << "TCPEndpoint: Send error :"
    00196              << getErrorString(sendMsg->error) << "\n";
    00197         close();
    00198         return;
    00199     }
    00200
    00201     // send was successfull.
    00202
    00203     int size = sizeOfDataToSend;
    00204     if (size>MAXSENDSIZE) size=MAXSENDSIZE;
    00205
    00206     // cout << "TCPEndpoint::SendCont - sending " << size << " bytes of " << sizeOfDataToSend << " from " << sendDataBuffer << "\n";
    00207
    00208     if (size > 0)  // Send rest of data
    00209     {
    00210
    00211        memcpy(sharedSendBuffer,sendDataBuffer,size);  // Copy data into shared memory buffer
    00212        sendSendMessage(size);
    00213        status = sending;
    00214
    00215        sizeOfDataToSend-=size;
    00216        (char*)sendDataBuffer += size;
    00217     }
    00218     else
    00219     {
    00220       status= connected;
    00221       onSendingDone();
    00222      // startReceiving();
    00223     }
    00224 }
    00225
    00226 void TCPEndpoint::sendSendMessage(int size)
    00227 {
    00228    // cout << "  SENDING " << size << " BYTES NOW ! ";
    00229    TCPEndpointSendMsg sendMsg(endpoint, sharedSendBuffer, size);
    00230    sendMsg.continuation = this;
    00231    sendMsg.Send(ipStackRef, *myOID_, *sendContSelector, sizeof(sendMsg));
    00232    status = sending;
    00233 }
    00234
    00235 void TCPEndpoint::onSendingDone()
    00236 {
    00237   return;
    00238 }
    00239
    00240
    00241 void TCPEndpoint::startReceiving()
    00242 {
    00243    // cout << "TCPEndpoint::startReceiving " << SystemCall::getCurrentSystemTime() << "\n";
    00244    status = connected;
    00245    TCPEndpointReceiveMsg receiveMsg(endpoint,sharedReceiveBuffer,1,8192);
    00246      // 1 = sizeMin = minumum size of data to be received
    00247    receiveMsg.continuation = this;
    00248    receiveMsg.Send(ipStackRef, *myOID_, *receiveContSelector, sizeof(receiveMsg));
    00249 }
    00250
    00251 void TCPEndpoint::receiveCont(antEnvMsg* msg)
    00252 {
    00253    // cout << "TCPEndpoint::ReceiveCont " << SystemCall::getCurrentSystemTime() << "\n";
    00254
    00255    TCPEndpointReceiveMsg* receiveMsg = (TCPEndpointReceiveMsg*) msg;
    00256    if (receiveMsg->error != TCP_SUCCESS)
    00257    {
    00258      if (receiveMsg->error == TCP_CONNECTION_BUSY)
    00259      {
    00260        // cout << "TCPEndpoint::ReveiceCont : Connection Busy \n" << flush ;
    00261        return;
    00262      }
    00263      else
    00264      {
    00265          cout << "TCPEndpoint::receiveCont() : Error receiving " <<
    00266              getErrorString(receiveMsg->error) << "\n";
    00267          onClose(receiveMsg->error);
    00268          close();
    00269      return;
    00270      }
    00271
    00272    }
    00273
    00274    // ASSERT(sharedReceiveBuffer == receiveMsg->buffer);
    00275
    00276    onReceive(sharedReceiveBuffer,receiveMsg->sizeMin);
    00277    // if (status!=sending)
    00278    {
    00279      startReceiving();
    00280      status=connected;
    00281    }
    00282
    00283 }
    00284
    00285 void TCPEndpoint::onReceive(void* Data, int size)
    00286 {
    00287
    00288 }
    00289
    00290 /*
    00291  * Closes the connection
    00292  */
    00293
    00294 int TCPEndpoint::close()
    00295 {
    00296    // cout << "TCPEndpoint::close() \n";
    00297    if ((status != closing) && (status != closed))
    00298    {
    00299      TCPEndpointCloseMsg closeMsg(endpoint);
    00300      closeMsg.continuation = this;
    00301      closeMsg.Send(ipStackRef, *myOID_, *closeContSelector, sizeof(closeMsg));
    00302      status=closing;
    00303    }
    00304    return(0);
    00305 }
    00306
    00307
    00308 void TCPEndpoint::onClose(int reason)
    00309 {
    00310
    00311 }
    00312
    00313 void TCPEndpoint::closeCont(antEnvMsg* msg)
    00314 {
    00315     // cout << "TCPEndpoint::closeCont WasListening " << wasListening << "\n";
    00316     TCPEndpointCloseMsg* closeMsg = (TCPEndpointCloseMsg*) msg;
    00317     if (closeMsg->error != TCP_SUCCESS)
    00318     {
    00319       cout << "TCPEndpoint::onClose() : error closing : "
    00320            << getErrorString(closeMsg->error) << "\n";
    00321     status = closed;
    00322     }
    00323     if (wasListening)
    00324     {
    00325       listen(port);
    00326     }
    00327
    00328 }
    00329
    00330
    00331 const char* TCPEndpoint::getErrorString(TCPEndpointError error)
    00332 {
    00333  switch (error)
    00334     {
    00335     case TCP_BUFFER_INVALID: return "TCP_BUFFER_INVALID (Address not in shared memory)";
    00336     case TCP_CONNECTION_BUSY: return "TCP_CONNECTION_BUSY (Another Operaation is in Progress)";
    00337     case TCP_CONNECTION_CLOSED: return "TCP_CONNECTION_CLOSED";
    00338     case TCP_CONNECTION_RESET: return "TCP_CONNECTION_RESET";
    00339     case TCP_CONNECTION_TIMEOUT: return "TCP_CONNECTION_TIMEOUT";
    00340     case TCP_FAIL: return "TCP_FAIL (no more information is avialble)";
    00341     case TCP_HOST_UNREACHABLE: return "TCP_HOST_UNREACHABLE";
    00342     case TCP_MESSAGE_TOO_LONG: return "TCP_MESSAGE_TOO_LONG";
    00343     case TCP_NETWORK_UNREACHABLE: return "TCP_NETWORK_UNREACHABLE";
    00344     case TCP_OPERATION_INVALID: return "TCP_OPERATION_INVALID";
    00345     case TCP_OPERATION_UNKNOWN: return "TCP_OPERATION_UNKNOWN";
    00346     case TCP_PORT_UNREACHABLE: return "TCP_PORT_UNREACHABLE";
    00347     case TCP_PROTOCOL_UNREACHABLE: return "TCP_PROTOCOL_UNREACHABLE";
    00348     case TCP_SUCCESS: return "TCP_SUCCESS";
    00349     case TCP_TIME_EXCEEDED: return "TCP_TIME_EXCEEDED";
    00350     case TCP_TTL_EXCEEDED: return "TCP_TTL_EXCEEDED";
    00351
    00352     default: return "TCP_UNKNOWN_ERROR please edit TCPEndpoint::getErrorSring";
    00353     }
    00354 }
    00355