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 // Start listening
00099 int TCPEndpoint::listen(int listenPort)
00100 {
00101   // Create the ANT-library endpoint
00102    antEnvCreateEndpointMsg tcpCreateMsg( EndpointType_TCP, 8192);
00103    tcpCreateMsg.Call(ipStackRef, sizeof(tcpCreateMsg));
00104 
00105    if (tcpCreateMsg.error != ANT_SUCCESS) 
00106    {
00107      cout << "TCPEndpoint::listen() : Can't create Endpoint, error " << antErrorString(tcpCreateMsg.error);
00108      return(1);
00109    }
00110 
00111   endpoint = tcpCreateMsg.moduleRef;
00112 
00113   cout << "TCPEndpoint::listen(" << listenPort << ") \n";
00114   port = listenPort;
00115 
00116   // start listening
00117   TCPEndpointListenMsg listenMsg(endpoint, IP_ADDR_ANY, port);
00118   listenMsg.continuation=this;
00119   VERIFY(*listenContSelector!=0); 
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   else
00141   {
00142      status=connected;
00143      wasListening=true;
00144      onConnect();
00145      startReceiving();
00146   }
00147 }
00148 
00149 // Sending 
00150 
00151 int TCPEndpoint::send(void* data,int size)
00152 {
00153    // cout << "TCPEndpoint::send(" << data << "," << size<< ") " << SystemCall::getCurrentSystemTime() << " \n";
00154    sendDataBuffer = data;
00155    sizeOfDataToSend = size;
00156 
00157    if (status == connected)
00158    {
00159        if (status != sending)
00160        {
00161        if (size>sharedSendBufferSize) size=sharedSendBufferSize;
00162            memcpy(sharedSendBuffer,sendDataBuffer,size);  // Copy data into shared memory buffer
00163      
00164       //     cout << "TCPEndpoint::send - Transfering " << size << " from " << sendDataBuffer << "\n";
00165            sendSendMessage(size);
00166 
00167            (char*)sendDataBuffer += size; 
00168            sizeOfDataToSend-=size;
00169 
00170            return(0);
00171        }
00172        else
00173        {
00174          return(-1);
00175        }
00176    }
00177    else
00178    {
00179      cout << "TCPEndpoint::send() : Not connected \n";
00180      return(-2);
00181    }
00182    
00183 }
00184 
00185 void TCPEndpoint::sendCont(antEnvMsg* msg)
00186 {
00187     // cout << "TCPEndpoint::SendCont " << SystemCall::getCurrentSystemTime() << "\n";
00188 
00189     TCPEndpointSendMsg* sendMsg = (TCPEndpointSendMsg*) msg;
00190     if (sendMsg->error != TCP_SUCCESS)
00191     {
00192         cout << "TCPEndpoint: Send error :" 
00193              << getErrorString(sendMsg->error) << "\n";
00194         close();
00195         return;
00196     }
00197 
00198     // send was successfull.
00199 
00200     int size = sizeOfDataToSend;
00201     if (size>sharedSendBufferSize) size=sharedSendBufferSize;
00202       
00203     // cout << "TCPEndpoint::SendCont - sending " << size << " bytes of " << sizeOfDataToSend << " from " << sendDataBuffer << "\n";
00204 
00205     if (size > 0)  // Send rest of data
00206     {
00207        memcpy(sharedSendBuffer,sendDataBuffer,size);  // Copy data into shared memory buffer
00208        sendSendMessage(size);
00209        status = sending;
00210        sizeOfDataToSend-=size;
00211        (char*)sendDataBuffer += size; 
00212     }
00213     else  // no more data to send
00214     {
00215       status= connected;
00216       onSendingDone();
00217     }
00218 }
00219 
00220 void TCPEndpoint::sendSendMessage(int size)
00221 {
00222    TCPEndpointSendMsg sendMsg(endpoint, sharedSendBuffer, size);
00223    sendMsg.continuation = this;
00224    sendMsg.Send(ipStackRef, *myOID_, *sendContSelector, sizeof(sendMsg));
00225    status = sending;
00226 }
00227 
00228 void TCPEndpoint::onSendingDone()
00229 {
00230   return;
00231 }
00232 
00233 
00234 void TCPEndpoint::startReceiving()
00235 {
00236    // cout << "TCPEndpoint::startReceiving " << SystemCall::getCurrentSystemTime() << "\n";
00237    status = connected;
00238    TCPEndpointReceiveMsg receiveMsg(endpoint,sharedReceiveBuffer,1,8192);
00239      // 1 = sizeMin = minumum size of data to be received 
00240    receiveMsg.continuation = this;
00241    receiveMsg.Send(ipStackRef, *myOID_, *receiveContSelector, sizeof(receiveMsg));
00242 }
00243 
00244 void TCPEndpoint::receiveCont(antEnvMsg* msg)
00245 {
00246    // cout << "TCPEndpoint::ReceiveCont " << SystemCall::getCurrentSystemTime() << "\n";
00247  
00248    TCPEndpointReceiveMsg* receiveMsg = (TCPEndpointReceiveMsg*) msg;
00249    if (receiveMsg->error != TCP_SUCCESS)
00250    {
00251      if (receiveMsg->error == TCP_CONNECTION_BUSY)
00252      {
00253        // cout << "TCPEndpoint::ReveiceCont : Connection Busy \n" << flush ;
00254        return;
00255      }
00256      else
00257      {
00258          cout << "TCPEndpoint::receiveCont() : Error receiving " << 
00259              getErrorString(receiveMsg->error) << "\n";
00260          onClose(receiveMsg->error);
00261          close();
00262      return;
00263      }
00264 
00265    }
00266  
00267    onReceive(sharedReceiveBuffer,receiveMsg->sizeMin);
00268    startReceiving();
00269    status=connected;
00270  }
00271 
00272 void TCPEndpoint::onReceive(void* Data, int size)
00273 {
00274  
00275 }
00276 
00277 /*
00278  * Closes the connection
00279  */
00280 
00281 int TCPEndpoint::close()
00282 {
00283    // cout << "TCPEndpoint::close() \n";
00284    if ((status != closing) && (status != closed)) 
00285    {
00286      TCPEndpointCloseMsg closeMsg(endpoint);
00287      closeMsg.continuation = this;
00288      closeMsg.Send(ipStackRef, *myOID_, *closeContSelector, sizeof(closeMsg));
00289      status=closing;
00290    }
00291    return(0);
00292 }
00293              
00294 
00295 void TCPEndpoint::onClose(int reason)
00296 {
00297   
00298 }
00299 
00300 void TCPEndpoint::closeCont(antEnvMsg* msg)
00301 {
00302     // cout << "TCPEndpoint::closeCont WasListening " << wasListening << "\n";
00303     TCPEndpointCloseMsg* closeMsg = (TCPEndpointCloseMsg*) msg;
00304     if (closeMsg->error != TCP_SUCCESS)
00305     {
00306       cout << "TCPEndpoint::onClose() : error closing : " 
00307            << getErrorString(closeMsg->error) << "\n";
00308     status = closed;
00309     }
00310     if (wasListening) 
00311     {
00312       listen(port);
00313     }
00314 
00315 }
00316 
00317 
00318 const char* TCPEndpoint::getErrorString(TCPEndpointError error)
00319 {
00320  switch (error)
00321     {
00322     case TCP_BUFFER_INVALID: return "TCP_BUFFER_INVALID (Address not in shared memory)";
00323     case TCP_CONNECTION_BUSY: return "TCP_CONNECTION_BUSY (Another operaation is in Progress)";
00324     case TCP_CONNECTION_CLOSED: return "TCP_CONNECTION_CLOSED";
00325     case TCP_CONNECTION_RESET: return "TCP_CONNECTION_RESET";
00326     case TCP_CONNECTION_TIMEOUT: return "TCP_CONNECTION_TIMEOUT";
00327     case TCP_FAIL: return "TCP_FAIL (no more information is avialble)";
00328     case TCP_HOST_UNREACHABLE: return "TCP_HOST_UNREACHABLE";
00329     case TCP_MESSAGE_TOO_LONG: return "TCP_MESSAGE_TOO_LONG";
00330     case TCP_NETWORK_UNREACHABLE: return "TCP_NETWORK_UNREACHABLE";
00331     case TCP_OPERATION_INVALID: return "TCP_OPERATION_INVALID";
00332     case TCP_OPERATION_UNKNOWN: return "TCP_OPERATION_UNKNOWN";
00333     case TCP_PORT_UNREACHABLE: return "TCP_PORT_UNREACHABLE";
00334     case TCP_PROTOCOL_UNREACHABLE: return "TCP_PROTOCOL_UNREACHABLE";
00335     case TCP_SUCCESS: return "TCP_SUCCESS";
00336     case TCP_TIME_EXCEEDED: return "TCP_TIME_EXCEEDED";
00337     case TCP_TTL_EXCEEDED: return "TCP_TTL_EXCEEDED";
00338           
00339     default: return "TCP_UNKNOWN_ERROR please edit TCPEndpoint::getErrorSring";
00340     }
00341 }
00342 
00343 
00344 
00345 
00346 /*
00347  * Change log :
00348  * 
00349  * $Log: TCPEndpoint.cpp,v $
00350  * Revision 1.2  2004/09/12 20:10:47  wachter
00351  * Documentation-fixes
00352  *
00353  * Revision 1.1.1.1  2004/05/22 17:23:40  cvsadm
00354  * created new repository GT2004_WM
00355  *
00356  * Revision 1.7  2004/01/26 13:44:07  wachter
00357  * shared-memory-buffers now have variable sizes
00358  *
00359  * Revision 1.6  2004/01/16 16:23:58  wachter
00360  * Bugfixes
00361  *
00362  * Revision 1.5  2004/01/03 18:57:50  wachter
00363  * Debug-communication working now
00364  *
00365  * Revision 1.4  2004/01/03 16:18:25  wachter
00366  * debug-communication mostly working now
00367  *
00368  * Revision 1.3  2003/12/21 19:27:03  wachter
00369  * Added classes for Sender/Receiver over TCP and UDP.
00370  * ( PLEASE DO NOT USE THIS NOW ! )
00371  *
00372  * Revision 1.2  2003/12/11 15:02:37  wachter
00373  * Low-level TCP and UDP functions for aperios now working.
00374  *
00375  * Revision 1.1  2003/12/03 14:21:52  wachter
00376  * Splitted IPEndpoint.*
00377  *
00378  * 
00379  */
00380 

Generated on Thu Sep 23 19:57:34 2004 for GT2004 by doxygen 1.3.6