Main Page | Class Hierarchy | Data Structures | File List | Data Fields | Globals

concreteconnection.cpp

Go to the documentation of this file.
00001 /*
00002  * $id: concreteconnection.cpp,v 1.18 2003/11/20 07:52:21 mattid Exp $
00003  *
00004  * COBAIN - Communications API for EPOC Environments
00005  * Copyright (C) 2002-2003 Matti Dahlbom, Matti Kokkola
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * Contact: Matti Dahlbom <matti@777-team.org>
00022  *          Matti Kokkola <matti.kokkola@iki.fi>
00023  */
00024 
00025 #include <e32base.h>
00026 #include <e32svr.h>
00027 #include <es_sock.h>
00028 
00029 //#include "clientservercommon.h"
00030 #include "serversideasynch.h"
00031 #include "concreteconnection.h"
00032 #include "Log.h"
00033 
00034 // constructs a 'normal' connection
00035 CConcreteConnection * CConcreteConnection::NewL(RSocket *aSocket,
00036                                                 CServerSession &aSession,
00037                         TInt aMtu)
00038 {
00039     CConcreteConnection *con = new (ELeave) CConcreteConnection(aSocket, 
00040                                                                 NULL,
00041                                                                 aSession,
00042                                 aMtu);
00043     CleanupStack::PushL(con);
00044     con->ConstructL(EFalse);
00045     CleanupStack::Pop(); // con
00046 
00047     return con;
00048 }
00049 
00050 // constructs a listening connection
00051 CConcreteConnection * CConcreteConnection::NewListeningL(RSocket *aSocket,
00052                                                          RSocketServ *aSocketServ,
00053                                                          CServerSession &aSession)
00054 {
00055     CConcreteConnection *con = new (ELeave) CConcreteConnection(aSocket, 
00056                                                                 aSocketServ,
00057                                                                 aSession,
00058                                 128);  // ##TODO## Resolve MTU!
00059     CleanupStack::PushL(con);
00060     con->ConstructL(ETrue);
00061     CleanupStack::Pop(); // con
00062     return con;
00063 }
00064 
00065 CConcreteConnection::CConcreteConnection(RSocket* aSocket, 
00066                                          RSocketServ *aSocketServ,
00067                                          CServerSession &aSession,
00068                      TInt aMtu)
00069     : iSocket(aSocket),
00070       iSocketServ(aSocketServ),
00071       iSession(aSession),
00072       iIsClosed(EFalse),
00073       iMtu(aMtu)
00074 {
00075 }
00076 
00077 CConcreteConnection::~CConcreteConnection()
00078 {
00079     if( !iIsListening ) {
00080         // deallocate self from session's socket table
00081         iSession.DeallocateConnection(this);
00082     }
00083 
00084     // must not delete
00085     iSocketServ = NULL;
00086 
00087     // close the connection and delete asynch handlers
00088     Close();
00089 }
00090 
00091 // constructs either a 'normal' or a listening connection
00092 // performs assertions on member data 
00093 void CConcreteConnection::ConstructL(TBool aIsListening)
00094 {
00095     if( iSocket == NULL ) User::Leave(ENullSocket);
00096 
00097     iIsListening = aIsListening;
00098 
00099     if( !aIsListening ) {
00100         Log::Print(_L("constructing connecting connection"));
00101 
00102         // connecting socket connection
00103         iSender = new (ELeave) CAsynchSend(this);
00104         iReceiver = new (ELeave) CAsynchReceive(this);
00105     } else {
00106         Log::Print(_L("constructing listening connection"));
00107 
00108         // listening connection
00109         iListener = new (ELeave) CAsynchListen(this);
00110     }
00111 }
00112 
00113 // sending is asynchronous - possible failure is handled by closing the socket
00114 void CConcreteConnection::SendL(TDesC8 *aBuf)
00115 {
00116     Log::Print(_L("CConcreteConnection::SendL()"));
00117 
00118     if( iSocket == NULL ) {
00119         Log::Print(_L("SendL(): socket closed!"));
00120 
00121         User::Leave(ESocketClosed);
00122     }
00123 
00124     // dispatch send. the client call will be completed immediately after 
00125     // initiating the send operation
00126     iSender->SendL(aBuf);
00127 }
00128 
00129 // listening is asynchronous
00130 void CConcreteConnection::ListenL(const RMessage &aMessage) 
00131 {
00132     Log::Print(_L("CConcreteConnection::ListenL()"));
00133 
00134     if( iSocket == NULL ) {
00135         Log::Print(_L("ListenL(): socket closed!"));
00136 
00137         User::Leave(ENoSocket);
00138     }
00139 
00140     // dispatch listener AO
00141     iListener->ListenL(aMessage);
00142 }
00143 
00144 void CConcreteConnection::ReceiveL(const RMessage &aMessage) 
00145 {
00146     Log::Print(_L("CConcreteConnection::Receive()"));
00147 
00148     if( iSocket == NULL ) {
00149         Log::Print(_L("ReceiveL(): socket closed!"));
00150 
00151         User::Leave(ESocketClosed);
00152     }
00153 
00154     // dispatch receive. the client call will be completed upon receiving data
00155     iReceiver->Receive(aMessage);
00156 }
00157 
00158 void CConcreteConnection::Close(TBool aImmediately)
00159 {
00160     // check if already closed
00161     if( iIsClosed ) return;
00162 
00163     Log::Print(_L("CConcreteConnection::Close(): listening: %d, imm: %d"),
00164         iIsListening, aImmediately);
00165 
00166     if( !iIsListening ) {
00167         Log::Print(_L("deleting sender & receiver"));
00168         iSender->Cancel();
00169         delete iSender;
00170         iSender = NULL;
00171         iReceiver->Cancel();
00172         delete iReceiver;
00173         iReceiver = NULL;
00174     } else {
00175         Log::Print(_L("deleting listener"));
00176         iListener->Cancel();
00177         delete iListener;
00178         iListener = NULL;
00179     }
00180 
00181     if( aImmediately && !iIsListening ) {
00182         Log::Print(_L("Calling Shutdown()"));
00183         TRequestStatus status;
00184         iSocket->Shutdown(RSocket::EImmediate, status);
00185         Log::Print(_L("Waiting for request completion"));
00186         User::WaitForRequest(status);
00187     }
00188 
00189     // close socket
00190     iSocket->Close();
00191 
00192     if( !iIsListening ) {
00193         // delete the socket instance
00194         delete iSocket;
00195         iSocket = NULL;
00196     }
00197 
00198     // mark the connection as closed
00199     iIsClosed = ETrue;
00200 
00201     Log::Print(_L("CConcreteConnection::Close(): exiting.."));
00202 }
00203 
00204 void CConcreteConnection::CancelListen()
00205 {
00206     iListener->Cancel();
00207 }
00208 
00209 void CConcreteConnection::CancelReceive()
00210 {
00211     iReceiver->Cancel();
00212 }
00213 
00214 // Returns maximum transfer unit of this connection as
00215 // defined when the connection was established.
00216 TInt CConcreteConnection::GetMTU()
00217 {
00218     return iMtu;
00219 }

Generated on Tue Jan 13 15:47:07 2004 for CobainAPIImplementation by doxygen 1.3.5