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

concreteconnection.cpp

Go to the documentation of this file.
00001 /*
00002  * 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 {
00038     CConcreteConnection *con = new (ELeave) CConcreteConnection(aSocket, 
00039                                                                 NULL,
00040                                                                 aSession);
00041     CleanupStack::PushL(con);
00042     con->ConstructL(EFalse);
00043     CleanupStack::Pop(); // con
00044 
00045     return con;
00046 }
00047 
00048 // constructs a listening connection
00049 CConcreteConnection * CConcreteConnection::NewListeningL(RSocket *aSocket,
00050                                                          RSocketServ *aSocketServ,
00051                                                          CServerSession &aSession)
00052 {
00053     CConcreteConnection *con = new (ELeave) CConcreteConnection(aSocket, 
00054                                                                 aSocketServ,
00055                                                                 aSession);
00056     CleanupStack::PushL(con);
00057     con->ConstructL(ETrue);
00058     CleanupStack::Pop(); // con
00059 
00060     return con;
00061 }
00062 
00063 CConcreteConnection::CConcreteConnection(RSocket* aSocket, 
00064                                          RSocketServ *aSocketServ,
00065                                          CServerSession &aSession)
00066     : iSocket(aSocket),
00067       iSocketServ(aSocketServ),
00068       iSession(aSession),
00069       iIsClosed(EFalse)
00070 {
00071 }
00072 
00073 CConcreteConnection::~CConcreteConnection()
00074 {
00075     if( !iIsListening ) {
00076         // deallocate self from session's socket table
00077         iSession.DeallocateConnection(this);
00078     }
00079 
00080     // must not delete
00081     iSocketServ = NULL;
00082 
00083     // close the connection and delete asynch handlers
00084     Close();
00085 }
00086 
00087 // constructs either a 'normal' or a listening connection
00088 // performs assertions on member data 
00089 void CConcreteConnection::ConstructL(TBool aIsListening)
00090 {
00091     if( iSocket == NULL ) User::Leave(ENullSocket);
00092 
00093     iIsListening = aIsListening;
00094 
00095     if( !aIsListening ) {
00096         Log::Print(_L("constructing connecting connection"));
00097 
00098         // connecting socket connection
00099         iSender = new (ELeave) CAsynchSend(this);
00100         iReceiver = new (ELeave) CAsynchReceive(this);
00101     } else {
00102         Log::Print(_L("constructing listening connection"));
00103 
00104         // listening connection
00105         iListener = new (ELeave) CAsynchListen(this);
00106     }
00107 }
00108 
00109 // sending is asynchronous - possible failure is handled by closing the socket
00110 void CConcreteConnection::SendL(TDesC8 *aBuf)
00111 {
00112     Log::Print(_L("CConcreteConnection::SendL()"));
00113 
00114     if( iSocket == NULL ) {
00115         Log::Print(_L("SendL(): socket closed!"));
00116 
00117         User::Leave(ESocketClosed);
00118     }
00119 
00120     // dispatch send. the client call will be completed immediately after 
00121     // initiating the send operation
00122     iSender->SendL(aBuf);
00123 }
00124 
00125 // listening is asynchronous
00126 void CConcreteConnection::ListenL(const RMessage &aMessage) 
00127 {
00128     Log::Print(_L("CConcreteConnection::ListenL()"));
00129 
00130     if( iSocket == NULL ) {
00131         Log::Print(_L("ListenL(): socket closed!"));
00132 
00133         User::Leave(ENoSocket);
00134     }
00135 
00136     // dispatch listener AO
00137     iListener->ListenL(aMessage);
00138 }
00139 
00140 void CConcreteConnection::ReceiveL(const RMessage &aMessage) 
00141 {
00142     Log::Print(_L("CConcreteConnection::Receive()"));
00143 
00144     if( iSocket == NULL ) {
00145         Log::Print(_L("ReceiveL(): socket closed!"));
00146 
00147         User::Leave(ESocketClosed);
00148     }
00149 
00150     // dispatch receive. the client call will be completed upon receiving data
00151     iReceiver->Receive(aMessage);
00152 }
00153 
00154 void CConcreteConnection::Close(TBool aImmediately)
00155 {
00156     // check if already closed
00157     if( iIsClosed ) return;
00158 
00159     Log::Print(_L("CConcreteConnection::Close(): listening: %d, imm: %d"),
00160         iIsListening, aImmediately);
00161 
00162     if( !iIsListening ) {
00163         Log::Print(_L("deleting sender & receiver"));
00164         iSender->Cancel();
00165         delete iSender;
00166         iSender = NULL;
00167         iReceiver->Cancel();
00168         delete iReceiver;
00169         iReceiver = NULL;
00170     } else {
00171         Log::Print(_L("deleting listener"));
00172         iListener->Cancel();
00173         delete iListener;
00174         iListener = NULL;
00175     }
00176 
00177     if( aImmediately && !iIsListening ) {
00178         Log::Print(_L("Calling Shutdown()"));
00179         TRequestStatus status;
00180         iSocket->Shutdown(RSocket::EImmediate, status);
00181         Log::Print(_L("Waiting for request completion"));
00182         User::WaitForRequest(status);
00183     }
00184 
00185     // close socket
00186     iSocket->Close();
00187 
00188     if( !iIsListening ) {
00189         // delete the socket instance
00190         delete iSocket;
00191         iSocket = NULL;
00192     }
00193 
00194     // mark the connection as closed
00195     iIsClosed = ETrue;
00196 
00197     Log::Print(_L("CConcreteConnection::Close(): exiting.."));
00198 }
00199 
00200 void CConcreteConnection::CancelListen()
00201 {
00202     iListener->Cancel();
00203 }
00204 
00205 void CConcreteConnection::CancelReceive()
00206 {
00207     iReceiver->Cancel();
00208 }
00209 

Generated on Mon Dec 8 10:26:07 2003 for CobainAPIImplementation by doxygen 1.3.5